/*
 * Copyright 2020-2030, MateCloud, DAOTIANDI Technology Inc All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * Author: pangu(7333791@qq.com)
 */
package com.yc.cloud.admin.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.yc.cloud.admin.common.UmsAdminConstants;
import com.yc.cloud.admin.dto.request.UmsAdminUpdateParam;
import com.yc.cloud.admin.dto.request.UmsAdminCreateParam;
import com.yc.cloud.admin.dto.request.UpdateAdminPasswordParam;
import com.yc.cloud.admin.service.UmsAdminService;
import com.yc.cloud.admin.service.UmsMenuService;
import com.yc.cloud.admin.service.UmsRoleService;
import com.yc.cloud.admin.vo.UmsAdminInfoVo;
import com.yc.cloud.admin.vo.UmsAdminVo;
import com.yc.cloud.common.basic.api.ResponseResult;
import com.yc.cloud.common.basic.dto.BasePageReqDTO;
import com.yc.cloud.common.basic.exception.Asserts;
import com.yc.cloud.common.orm.CommonPage;
import com.yc.cloud.admin.service.FaceRecognitionService;
import com.yc.cloud.admin.dto.request.FaceAddFileReqDTO;
import com.yc.cloud.admin.dto.response.FaceAddFileRespDTO;
import com.yc.cloud.common.oss.service.OssFileService;
import com.yc.cloud.entity.UmsAdmin;
import com.yc.cloud.entity.UmsRole;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 后台用户表 前端控制器
 * </p>
 *
 * @author JackGu
 * @since 2022-09-11
 */
@Slf4j
@RestController
@RequestMapping("/admin")
@Api(value = "后台用户表", tags = "后台用户表接口")
public class UmsAdminController {

    @Value("${jwt.tokenHeader}")
    private String tokenHeader;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Resource
    private UmsAdminService umsAdminService;

    @Resource
    private UmsAdminService adminService;

    @Resource
    private UmsRoleService roleService;

    @Resource
    private UmsMenuService umsMenuService;

    @Resource
    private OssFileService ossFileService;

    @Resource
    private FaceRecognitionService faceRecognitionService;

    @GetMapping("/list")
    @ApiOperation(value = "用户列表", notes = "支持分页查询,字段模糊匹配,排序等")
    public ResponseResult<CommonPage<UmsAdminVo>> list(BasePageReqDTO param) {
        CommonPage<UmsAdminVo> result = umsAdminService.list(param);
        return ResponseResult.success(result);
    }


    @GetMapping("/{id}")
    @ApiOperation(value = "详情", notes = "根据ID查询")
    public ResponseResult<UmsAdmin> getItem(@PathVariable @ApiParam(value = "ID", required = true) Long id) {
        return ResponseResult.success(umsAdminService.getById(id));
    }


    @PostMapping("/create")
    @ApiOperation(value = "添加用户", notes = "添加后台用户，如果设置了头像(icon)会自动调用人脸识别服务")
    public ResponseResult<UmsAdmin> create(@Validated @RequestBody UmsAdminCreateParam umsAdmin) {
        val result = umsAdminService.create(umsAdmin);
        if (result != null) {
            return ResponseResult.success(result);
        }
        return ResponseResult.failed();
    }


    @ApiOperation(value = "删除用户", notes = "通过ID删除（同时删除关联的人脸数据）")
    @PostMapping(value = "/delete/{id}")
    public ResponseResult<Long> delete(@PathVariable @ApiParam(value = "ID", required = true) Long id) {
        boolean result = umsAdminService.delete(id);
        if (result) {
            return ResponseResult.success();
        }
        return ResponseResult.failed();
    }


    @PostMapping("/delete/batch")
    @ApiOperation(value = "批量删除", notes = "通过id逗号分隔,批量删除")
    public ResponseResult<List<Long>> delete(@RequestParam List<Long> ids) {
        val result = umsAdminService.removeByIds(ids);
        if (result) {
            return ResponseResult.success();
        }
        return ResponseResult.failed();
    }


    @ApiOperation(value = "修改用户", notes = "通过ID修改，如果更新了头像(icon)会自动调用人脸识别服务")
    @PostMapping(value = "/update/{id}")
    public ResponseResult<Long> update(@PathVariable @ApiParam(value = "ID", required = true) Long id, @Validated @RequestBody UmsAdminUpdateParam umsAdmin) {
        val result = umsAdminService.update(id, umsAdmin);
        if (result > 0) {
            return ResponseResult.success();
        }
        return ResponseResult.failed();
    }


    @ApiOperation(value = "获取当前登录用户信息")
    @GetMapping("/info")
    public ResponseResult<UmsAdminInfoVo> getAdminInfo() {
        UmsAdmin umsAdmin = umsAdminService.getAdmin();
        
        // 构建VO对象，使用BeanUtils复制所有字段（密码字段不在VO中，自动忽略）
        UmsAdminInfoVo vo = new UmsAdminInfoVo();
        BeanUtils.copyProperties(umsAdmin, vo);
        
        // 转换头像文件ID为URL
        if (StrUtil.isNotEmpty(umsAdmin.getIcon())) {
            String iconUrl = ossFileService.getOssFileUrl(umsAdmin.getIcon());
            vo.setIconUrl(iconUrl);
        }
        
        // 获取用户菜单列表
        vo.setMenus(umsMenuService.getMenuList(umsAdmin.getId()));
        
        // 获取用户角色列表
        List<UmsRole> roleList = roleService.getRoleList(umsAdmin.getId());
        if (CollUtil.isEmpty(roleList)) {
            Asserts.fail(UmsAdminConstants.USER_ROLE_EMPTY);
        }
        List<String> roles = roleList.stream().map(UmsRole::getName).collect(Collectors.toList());
        vo.setRoles(roles);
        
        return ResponseResult.success(vo);
    }

    @ApiOperation("给用户分配角色")
    @RequestMapping(value = "/role/update", method = RequestMethod.POST)
    @ResponseBody
    public ResponseResult<Integer> updateRole(@RequestParam("adminId") Long adminId, @RequestParam("roleIds") List<Long> roleIds) {
        int count = roleService.updateRole(adminId, roleIds);
        if (count >= 0) {
            return ResponseResult.success(count);
        }
        return ResponseResult.failed();
    }

    @ApiOperation("获取指定用户的角色")
    @RequestMapping(value = "/role/{adminId}", method = RequestMethod.GET)
    @ResponseBody
    public ResponseResult<List<UmsRole>> getRoleList(@PathVariable Long adminId) {
        List<UmsRole> roleList = roleService.getRoleList(adminId);
        return ResponseResult.success(roleList);
    }


    @ApiOperation(value = "登出功能")
    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    @ResponseBody
    public ResponseResult<String> logout() {
        adminService.logout();
        return ResponseResult.success("登出成功");
    }


    @ApiOperation("修改指定用户密码")
    @RequestMapping(value = "/updatePassword", method = RequestMethod.POST)
    @ResponseBody
    public ResponseResult<Integer> updatePassword(@Validated @RequestBody UpdateAdminPasswordParam updatePasswordParam) {
        int status = adminService.updatePassword(updatePasswordParam);
        if (status > 0) {
            return ResponseResult.success(status);
        } else if (status == -1) {
            return ResponseResult.failed("提交参数不合法");
        } else if (status == -2) {
            return ResponseResult.failed("找不到该用户");
        } else if (status == -3) {
            return ResponseResult.failed("旧密码错误");
        } else {
            return ResponseResult.failed();
        }
    }


    @ApiOperation("修改帐号状态")
    @RequestMapping(value = "/updateStatus/{id}", method = RequestMethod.POST)
    @ResponseBody
    public ResponseResult<Void> updateStatus(@PathVariable Long id, @RequestParam(value = "status") Integer status) {
        UmsAdmin umsAdmin = new UmsAdmin();
        umsAdmin.setStatus(status);
        umsAdmin.setId(id);
        if (adminService.updateById(umsAdmin)) {
            return ResponseResult.success();
        }
        return ResponseResult.failed();
    }

    @ApiOperation(value = "刷新token")
    @RequestMapping(value = "/refreshToken", method = RequestMethod.GET)
    @ResponseBody
    public ResponseResult<String> refreshToken(HttpServletRequest request) {
        String token = request.getHeader(tokenHeader);
        String refreshToken = adminService.refreshToken(token);
        if (refreshToken == null) {
            return ResponseResult.failed("token已经过期！");
        }
        val result = tokenHead + refreshToken;
        return ResponseResult.success(result);
    }

    @ApiOperation(value = "上传用户人脸照片", notes = "上传用户人脸照片到人脸识别服务，返回人脸ID。在创建或更新用户时使用此ID。")
    @PostMapping("/face/upload")
    public ResponseResult<FaceAddFileRespDTO> uploadFaceImage(
            @ApiParam(value = "人脸照片文件", required = true) @RequestParam("file") MultipartFile file,
            @ApiParam(value = "用户ID（用于生成faceId，创建用户时可不传）", required = false) @RequestParam(value = "userId", required = false) Long userId,
            @ApiParam(value = "用户名（用于识别）", required = false) @RequestParam(value = "username", required = false) String username) {

        if (file == null || file.isEmpty()) {
            return ResponseResult.failed("人脸照片不能为空");
        }

        try {
            // 生成人脸ID：使用 user_{userId} 或 user_{username} 格式
            String personId;
            if (userId != null) {
                personId = "user_" + userId;
            } else if (StrUtil.isNotBlank(username)) {
                personId = "user_" + username;
            } else {
                // 如果都没有，使用时间戳
                personId = "user_" + System.currentTimeMillis();
            }

            // 构建请求参数
            FaceAddFileReqDTO reqDTO = FaceAddFileReqDTO.builder()
                    .personId(personId)
                    .personName(username) // 人脸名称使用用户名
                    .metaInfo(null)       // 扩展信息暂不使用
                    .build();

            // 调用人脸识别服务添加人脸
            FaceAddFileRespDTO result = faceRecognitionService.addFaceFile(file, reqDTO);

            if (result != null && result.isSuccess()) {
                return ResponseResult.success(result);
            } else {
                return ResponseResult.failed("人脸照片上传失败：" + (result != null ? result.getMsg() : "未知错误"));
            }

        } catch (Exception e) {
            log.error("上传用户人脸照片异常", e);
            return ResponseResult.failed("人脸照片上传失败：" + e.getMessage());
        }
    }

    @ApiOperation(value = "删除用户人脸照片", notes = "从人脸识别服务中删除用户的人脸信息")
    @PostMapping("/face/delete/{id}")
    public ResponseResult<Void> deleteFaceImage(
            @ApiParam(value = "用户ID", required = true) @PathVariable Long id) {

        try {
            UmsAdmin admin = adminService.getById(id);
            if (admin == null) {
                return ResponseResult.failed("用户不存在");
            }

            if (StrUtil.isBlank(admin.getFaceId())) {
                return ResponseResult.failed("该用户未录入人脸信息");
            }

            // 调用人脸识别服务删除人脸
            Boolean deleted = faceRecognitionService.deleteFace(admin.getFaceId());

            if (deleted) {
                // 清除数据库中的 faceId
                admin.setFaceId(null);
                adminService.updateById(admin);
                return ResponseResult.success();
            } else {
                return ResponseResult.failed("删除人脸失败");
            }

        } catch (Exception e) {
            log.error("删除用户人脸照片异常", e);
            return ResponseResult.failed("删除人脸失败：" + e.getMessage());
        }
    }

}
